package org.javahispano.javacup.tacticas_aceptadas.degoo;

import java.awt.Color;
import org.javahispano.javacup.modelo.*;
import java.util.List;
import java.util.LinkedList;
import java.util.Random;


public class TacticaBenitos implements Tactica {

    Posicion alineacion1[]=new Posicion[]{
        new Posicion(0.0, -49.699),
        new Posicion(-15.455, -25.695),//new Posicion(-15.455, -29.695),
        new Posicion(0.476, -26.12),//new Posicion(0.476, -31.12),
        new Posicion(14.741, -25.357),//new Posicion(14.741, -31.357),
        new Posicion(-5.944, -13.303),
        new Posicion(5.231, -10.514),//new Posicion(5.231, -0.514),
        new Posicion(-15.161, -16.74),//new Posicion(-21.161, -1.74),
        new Posicion(10.699, 9.74),
        new Posicion(-7.566, 24.833),//new Posicion(-3.566, 31.833),
        new Posicion(0.0, 16.816),
        new Posicion(6.993, 23.595)//new Posicion(4.993, 31.595)
    };

    Posicion alineacion2[]=new Posicion[]{
        new Posicion(0.2595419847328244,-50.41044776119403),
        new Posicion(-11.16030534351145,-31.082089552238806),
        new Posicion(11.16030534351145,-31.6044776119403),
        new Posicion(27.251908396946565,-27.94776119402985),
        new Posicion(-29.84732824427481,-26.902985074626866),
        new Posicion(22.11188811188811,-9.264705882352942),
        new Posicion(-22.825174825174827,-7.126696832579185),
        new Posicion(-1.188811188811189,-13.540723981900454),
        new Posicion(-0.23776223776223776,-1.1877828054298643),
        new Posicion(-10.6993006993007,-4.038461538461538),
        new Posicion(14.027972027972028,-5.463800904977376)
    };

    Posicion alineacion3[]=new Posicion[]{
        new Posicion(0.2595419847328244,-50.41044776119403),
        new Posicion(-11.16030534351145,-31.082089552238806),
        new Posicion(11.16030534351145,-31.6044776119403),
        new Posicion(26.732824427480914,-20.111940298507463),
        new Posicion(-29.32824427480916,-21.67910447761194),
        new Posicion(-1.188811188811189,-24.468325791855204),
        new Posicion(-22.825174825174827,-3.5633484162895925),
        new Posicion(19.020979020979023,-4.98868778280543),
        new Posicion(-2.377622377622378,-14.25339366515837),
        new Posicion(9.272727272727272,-12.59049773755656),
        new Posicion(-14.74125874125874,-12.828054298642533)
    };

   Posicion alineacion4[]=new Posicion[]{
        new Posicion(0.0, -49.649),
        new Posicion(-15.455, -25.695),
        new Posicion(0.476, -25.12),
        new Posicion(14.741, -25.357),
        new Posicion(-5.944, -16.303),
        new Posicion(10.231, -8.514),
        new Posicion(-27.161, -6.74),
        new Posicion(10.699, 9.74),
        new Posicion(-7.566, 18.833),
        new Posicion(5.0, 14.816),
        new Posicion(4.993, 20.595)
    };



    class TacticaDetalleImpl implements TacticaDetalle {

        public String getNombre() {
            return "Benitos";
        }

        public String getPais() {
            return "España";
        }

        public String getEntrenador() {
            return "Diego Navarro Tarraga";
        }

        public Color getColorCamiseta() {
            return new Color(51, 51, 255);
        }

        public Color getColorPantalon() {
            return new Color(255, 255, 255);
        }

        public Color getColorFranja() {
            return new Color(255, 255, 255);
        }

        public Color getColorCalcetas() {
            return new Color(255, 255, 255);
        }

        public Color getColorPortero() {
            return new Color(255, 204, 0        );
        }

        public EstiloUniforme getEstilo() {
            return EstiloUniforme.FRANJA_HORIZONTAL;
        }

        public Color getColorCamiseta2() {
            return new Color(255, 255, 255);
        }

        public Color getColorPantalon2() {
            return new Color(51, 51, 255);
        }

        public Color getColorFranja2() {
            return new Color(255, 0, 51);
        }

        public Color getColorCalcetas2() {
            return new Color(23, 23, 113);
        }

        public Color getColorPortero2() {
            return new Color(102, 0, 102        );
        }

        public EstiloUniforme getEstilo2() {
            return EstiloUniforme.FRANJA_DIAGONAL;
        }

        class JugadorImpl implements JugadorDetalle {

            String nombre;
            int numero;
            Color piel, pelo;
            double velocidad, remate, presicion;
            boolean portero;
            Posicion posicion;

            public JugadorImpl(String nombre, int numero, Color piel, Color pelo,
                    double velocidad, double remate, double presicion, boolean portero) {
                this.nombre=nombre;
                this.numero=numero;
                this.piel=piel;
                this.pelo=pelo;
                this.velocidad=velocidad;
                this.remate=remate;
                this.presicion=presicion;
                this.portero=portero;
            }

            public String getNombre() {
                return nombre;
            }

            public Color getColorPiel() {
                return piel;
            }

            public Color getColorPelo() {
                return pelo;
            }

            public int getNumero() {
                return numero;
            }

            public boolean esPortero() {
                return portero;
            }

            public double getVelocidad() {
                return velocidad;
            }

            public double getRemate() {
                return remate;
            }

            public double getPresicion() {
                return presicion;
            }

        }

        public JugadorDetalle[] getJugadores() {
            return new JugadorDetalle[]{
                new JugadorImpl("Benito", 1, new Color(255,200,150), new Color(50,0,0),1.0d,0.8d,1.0d, true),
                new JugadorImpl("Camela", 2, new Color(255,200,150), new Color(50,0,0),0.69d,0.62d,0.71d, false),
                new JugadorImpl("Iribar", 3, new Color(255,200,150), new Color(50,0,0),0.88d,0.76d,0.5d, false),
                new JugadorImpl("McMartigan", 4, new Color(255,200,150), new Color(50,0,0),0.79d,0.7d,0.5d, false),
                new JugadorImpl("Oman Biyic", 5, new Color(255,200,150), new Color(50,0,0),0.63d,1.0d,0.69d, false),
                new JugadorImpl("Yoshi", 6, new Color(255,200,150), new Color(50,0,0),1.0d,1.0d,0.83d, false),
                new JugadorImpl("Enjoy", 7, new Color(255,200,150), new Color(50,0,0),0.94d,0.91d,0.61d, false),
                new JugadorImpl("Cotarro", 8, new Color(255,200,150), new Color(50,0,0),0.61d,0.76d,0.65d, false),
                new JugadorImpl("Cataclas", 9, new Color(255,200,150), new Color(50,0,0),0.97d,1.0d,1.0d, false),
                new JugadorImpl("Ouh Yeah", 10, new Color(255,200,150), new Color(50,0,0),0.97d,0.97d,1.0d, false),
                new JugadorImpl("Bustingorri", 11, new Color(255,200,150), new Color(50,0,0),1.0d,1.0d,1.0d, false)
            };
        }
    }

    TacticaDetalle detalle=new TacticaDetalleImpl();
    public TacticaDetalle getDetalle() {
        return detalle;
    }

    public Posicion[] getPosicionSaca(SituacionPartido sp) {
    return alineacion2;
    }

    public Posicion[] getPosicionRecive(SituacionPartido sp) {
    return alineacion3;
    }

    Random rand = new Random();
    LinkedList<Comando> comandos = new LinkedList<Comando>();
    int to_pase = -1;

    public List<Comando> ejecutar(SituacionPartido sp) {
        boolean pase = false;
        boolean balon_lejos = false;
        int counter;
        comandos.clear();
        boolean alto = false;
        Posicion mios[] = sp.misJugadores();
        double angulo = 0;
        double delta = 0;
        int[] con_orden = new int[11];
        for (counter = 0; counter <= 10; counter++)
            con_orden[counter] = 0;
        double distancia = 0;
        double fuerza = 0;

        Posicion contra[] = sp.rivales();

        int cerca[] = sp.balon().indicesMasCercanos(mios);
        //el jugador mas cercano sigue al balon
        double max = Math.min(sp.balon().getX(), 3);
        max = Math.max(max, -3);
        comandos.add(new ComandoIrA(0, new Posicion(max, -50.5)));
        comandos.add(new ComandoIrA(cerca[0], sp.balon()));
        con_orden[cerca[0]] = 1;
        comandos.add(new ComandoIrA(cerca[1], sp.balon()));
        con_orden[cerca[1]] = 1;
        con_orden[0] = 1;
        
        // Que el portero no se pase saliendo....
        if (mios[0].getY() > -36)
            comandos.add(new ComandoIrA(0, new Posicion(max, -50.5)));
        int rematan[] = sp.puedenRematar();
        if (rematan.length > 0)
        {
            for(int remata: rematan)
            {
                if (remata == 0 || sp.balon().getY() < -30)
                {
                    balon_lejos = true;
                    delta = 8 * rand.nextDouble();
                    if (rand.nextDouble() > 0.5) angulo = 110 + delta;
                    else angulo = 70 + delta;
                    comandos.add(new ComandoGolpearBalon(remata, angulo, (.7 + rand.nextDouble() * .5), true));
                    to_pase = -1;
                    pase = true;
                }
                else
                {
                    distancia = sp.misJugadores()[remata].distancia(Constantes.centroArcoSup);
                    if (distancia >= 58) balon_lejos = true;
                    else balon_lejos = false;
                    if (distancia < 30)
                    {
                        to_pase = -1;
                        if (distancia >= 16)
                        {                            
                            double f = rand.nextDouble() * 0.2 + 0.7;
                            comandos.add(new ComandoGolpearBalon(remata, Constantes.centroArcoSup, f, true));
                        }
                        else
                        {
                            if (mios[remata].getX() <=0 && mios[remata].getX() >= -4) {
                                double x_tiro = 2.14;
                                double y_tiro = Constantes.LARGO_CAMPO_JUEGO / 2;
                                comandos.add(new ComandoGolpearBalon(remata, new Posicion(x_tiro, y_tiro), 0.9, false));
                            }
                            else {
                                if (mios[remata].getX() >=0 && mios[remata].getX() <= 4) {
                                    double x_tiro = -2.14;
                                    double y_tiro = Constantes.LARGO_CAMPO_JUEGO / 2;
                                    comandos.add(new ComandoGolpearBalon(remata, new Posicion(x_tiro, y_tiro), 0.9, false));
                                }
                                else
                                    comandos.add(new ComandoGolpearBalon(remata, Constantes.centroArcoSup, 0.9, false));
                            }
                        }
                    }
                    else
                    {
                        int[] cercanos = mios[remata].indicesMasCercanos(mios);
                        counter = 0;
                        pase = false;
                        while (counter < cercanos.length && !pase)
                        {
                            double y_da_pase = sp.misJugadores()[remata].getY();
                            double y_recibe = sp.misJugadores()[cercanos[counter]].getY();
                            if ( (y_recibe - y_da_pase) > 7 )
                            {
                                double y = sp.misJugadores()[cercanos[counter]].getY();
                                double x = sp.misJugadores()[cercanos[counter]].getX();
                                //y += 1;
                                //x += 1;

                                //int[] mamones = sp.misJugadores()[cercanos[counter]].indicesMasCercanos(contra);
                                //if (sp.misJugadores()[cercanos[counter]].distancia(contra[mamones[0]]) <= 6)
                                    //alto = true;
                                //comandos.add(new ComandoGolpearBalon(remata, sp.misJugadores()[cercanos[counter]], (.5 + rand.nextDouble() * .5), alto));
                                distancia = mios[remata].distancia(new Posicion(x,y));
                                angulo = 30;
                                if (distancia <= 5) fuerza = 0.34;
                                else if (distancia <= 12) fuerza = 0.5;
                                else if (distancia <= 20) fuerza = 0.75;
                                else if (distancia <= 26) { angulo = 30; fuerza = 0.9; }
                                else { angulo = 30; fuerza = 1; }
                                //comandos.add(new ComandoGolpearBalon(remata, new Posicion(x, y), (.5 + rand.nextDouble() * .5), alto));
                                comandos.add(new ComandoGolpearBalon(remata, new Posicion(x, y), fuerza, angulo));
                                comandos.add(new ComandoIrA(cercanos[counter], new Posicion(x, y)));
                                con_orden[cercanos[counter]] = 1;
                                to_pase = cercanos[counter];
                                pase = true;
                            }
                            counter++;
                        }
                        if (!pase)
                            comandos.add(new ComandoGolpearBalon(remata, Constantes.centroArcoSup, 1, true));
                    }
                }
            }
        }

        boolean ya = false;
        for(counter = 1; counter <= 10; counter++)
        {
            if (con_orden[counter] == 0 && counter != to_pase)
            {
                if (sp.balon().getY() < 28 && (mios[counter].getY() > sp.balon().getY()) && ((alineacion1[counter].distancia(mios[counter]) < 15) && !ya))
                {
                    comandos.add(new ComandoIrA(counter, sp.balon()));
                    ya = true;
                }
                else
                {
                    if (balon_lejos == true)
                    {
                        comandos.add(new ComandoIrA(counter, alineacion4[counter]));
                    }
                    else
                    {
                        comandos.add(new ComandoIrA(counter, alineacion1[counter]));
                    }
                }
            }
        }

        return comandos;
    }
}